/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			pgspace.h
  \date			Aug 2012
  \author		TNick

  \brief		Contains the definition for PgSpace class


*//*


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __PGSPACE_INC__
#define __PGSPACE_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<cpg/cpg.h>
#include	<QList>
#include	<QColor>
#include	<cpg/logic/pgittree.h>
#include	<cpg/properties/iprop.h>
#include	<cpg/control/pgguidermanager.h>

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */



namespace	cpg		{

class	PrintParams;
class	CpgDoc;
class	PgLaySpc;
class	PgLayGlob;
class	PgLayer;
class	PgCtx;


/**
*	@brief	A space inside a document
*/
class CPGSHARED_EXPORT PgSpace	: public GuiderManager, public IProp			{
	BBM_TRACK( PgSpace );

	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */

	friend class	ASpaceID;
	friend class	CpgDoc;
	friend class	CpgLibrary;
	friend class	PgLayGlob;

	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */

private:

#	define	PGPROP( label, variable, pro_type, on_change, descr, descr_long )

	/**
	*	@brief	name of this space
	*/
	QString						s_name_;


	/**
	*	@brief	associated document
	*/
	CpgDoc *						assoc_doc_;


	/**
	*	@brief	list of printing configurations
	*
	*	At least one (default) configuration must exist in all instances.
	*
	*	The instances are owned by this class.
	*/
	QList<PrintParams*>			print_params_;


	/**
	*	@brief	the index of the current configuration
	*/
	int							crt_print_;


	/**
	*	@brief	color for the background
	*/
	QRgb						clear_col_;



	/**
	*	@brief	the list of layers rooted in this space
	*/
	QList<PgLaySpc*>			local_ly_lst_;


	/**
	*	@brief	the list of global layers
	*/
	QList<PgItTree*>			glob_ly_list_;


	/**
	*	@brief	pointer to current layer (may be NULL)
	*/
	PgLayer *					crt_layer_;


	/**
	*	@brief	current color
	*/
	int							crt_color_;


	/**
	*	@brief	current line pattern
	*/
	int							crt_lnpatt_;


	/**
	*	@brief	current line pattern scale
	*/
	int							crt_lnpatt_scl_;


	/**
	*	@brief	current line weight
	*/
	int							crt_weight_;






	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:


	/**
	*	@brief	constructor;
	*/
	PgSpace				( const QString & s_name );


	/**
	*	@brief	constructor; uses the other space as a template
	*
	*	The constructor DOES NOT insert the space in the document.
	*/
	PgSpace				( CpgDoc * doc, PgSpace * space );


	/**
	*	@brief	destructor;
	*/
	virtual				~PgSpace		( void );


	/**
	*	@brief	get the name of the space
	*/
	inline CpgDoc *		document			( void ) const
	{ return assoc_doc_; }


protected:


	/**
	*	@brief	get the name of the space
	*/
	inline void			setAssocDoc				( CpgDoc * doc )
	{ assoc_doc_ = doc; }


public:


	/**
	*	@brief	get the name of the space
	*/
	inline QString		name					( void ) const
	{ return s_name_; }


	/**
	*	@brief	change the name of the space to specified name
	*/
	bool				setName					( const QString & s_new );


	/**
	*	@brief	color for the background
	*/
	inline QRgb			background				( void )
	{ return clear_col_; }


	/**
	*	@brief	color for special foreground
	*/
	QRgb				qtSpecialForeGround		( PgCtx & ctx );


	/**
	*	@brief	color for special background
	*/
	QRgb				qtSpecialBackGround		( PgCtx & ctx );


	/* ******************************************************************* */
	/** @name 	Layer related methods                                      */
	/* ******************************************************************* */
	///@{



	/**
	*	@brief	appends a layer to the ones associated with this space
	*/
	void				addLayer			( PgLaySpc * itm )
	{
		if ( local_ly_lst_.contains( itm ) )
		{
			Q_ASSERT( false );
			return;
		}
		local_ly_lst_.append( itm );
	}


	/**
	*	@brief	appends a global layer to the ones associated with this space
	*/
	inline int			addLayer			( PgItTree * it_lst )
	{
		glob_ly_list_.append( it_lst );
		return glob_ly_list_.count() - 1;
	}


	/**
	*	@brief	appends a layer to the ones associated with this space
	*
	*	This may be a local or a global layer. For global layers a
	*	PgItTree is created and added to list.
	*/
	bool				addLayer			( PgLayer * layer );




	/**
	*	@brief	removes a layer from the ones associated with this space
	*/
	bool				remLayer			( PgLaySpc * itm )
	{
		int idx = local_ly_lst_.indexOf( itm );
		if ( idx == -1 )
		{
			Q_ASSERT( false );
			return false;
		}
		local_ly_lst_.removeAt( idx );
		return true;
	}


	/**
	*	@brief	removes a layer from the ones associated with this space
	*/
	bool				remLayer			( int itm )
	{
		if ( ( itm < 0 ) || ( itm >= local_ly_lst_.count() ) )
		{
			Q_ASSERT( false );
			return false;
		}
		local_ly_lst_.removeAt( itm );
		return true;
	}


	/**
	*	@brief	removes a global layer from the ones associated with this space
	*
	*	The ownership of the PgItTree is transfered to the caller.
	*/
	PgItTree *			remGlobalLayer		( PgLayGlob * itm );


	/**
	*	@brief	removes a global layer from the ones associated with this space
	*
	*	The ownership of the PgItTree is transfered to the caller.
	*/
	PgItTree *			remGlobalLayer		( int itm )
	{
		PgItTree * ret;
		if ( ( itm < 0 ) || ( itm >= glob_ly_list_.count() ) )
		{
			Q_ASSERT( false );
			return NULL;
		}
		ret = glob_ly_list_.at( itm );
		glob_ly_list_.removeAt( itm );
		return ret;
	}


	/**
	*	@brief	get current layer
	*/
	inline PgLayer *	currentLayer		( void )
	{ return crt_layer_; }


	/**
	*	@brief	change current layer; may fail if the layer is not found
	*/
	bool				setCurrentLayer		( PgLayer * new_val );


	/**
	*	@brief	get the items for specified global layer
	*/
	PgItTree *			items				( PgLayGlob * layer );



	/**
	*	@brief	return the list of layers associated with this space
	*/
	inline QList<PgLaySpc*>	layers			( void )
	{ return local_ly_lst_; }


	/**
	*	@brief	return the number of local layers
	*/
	inline int			layerCount		( void ) const
	{ return local_ly_lst_.count(); }


	/**
	*	@brief	return the number of global layers hosted in this space
	*/
	inline int			layerGlbCount		( void ) const
	{ return glob_ly_list_.count(); }



	/**
	*	@brief	get the layer that has this name
	*
	*	After seaching local layers, if \b b_glb is true, global
	*	layers are also searched.
	*/
	PgLayer *			layerByName			(
			const QString &				s_name,
			bool						b_glb = false
			) const;


	/**
	*	@brief	get the index where a layer resides or -1 if it is not
	*	part of the space
	*/
	int					layerIndex			(
			PgLaySpc *					layer
			) const;



	/**
	*	@brief	get an unique name for a layer
	*/
	QString				layerUniqName		( void ) const;


	///@}
	/* ******************************************************************* */

	/* ******************************************************************* */
	/** @name 	Printing spport                                            */
	/* ******************************************************************* */
	///@{


	/**
	*	@brief	list of printing configurations
	*
	*	At least one (default) configuration must exist in all instances
	*/
	inline QList<PrintParams*>		printParams			( void ) const
	{ return print_params_; }


	/**
	*	@brief	the index of the current configuration
	*/
	inline int						crtPrintIndex		( void ) const
	{ return crt_print_; }


	/**
	*	@brief	get a parameter at a certain index
	*/
	inline PrintParams*				printParam			( int i ) const
	{
		if ( ( i < 0 ) || ( i >= print_params_.count() ) )
			return NULL;
		return print_params_.at( i );
	}


	/**
	*	@brief	get default parameter
	*/
	inline PrintParams*				crtPrintParam		( void ) const
	{
		return print_params_.at( crt_print_ );
	}


	/**
	*	@brief	add a new print parameter to the list
	*/
	inline int						addPrintParam		( PrintParams * pp )
	{
		Q_ASSERT( print_params_.contains( pp ) == false );
		print_params_.append( pp );
		return print_params_.count() - 1;
	}


	/**
	*	@brief	the index of the current configuration
	*/
	inline void						setCrtPrintIndex	( int new_crt )
	{
		if ( ( new_crt < 0 ) || ( new_crt >= print_params_.count() ) )
			return;
		crt_print_ = new_crt;
	}


	/**
	*	@brief	remove a printer setting from here
	*/
	bool							removePrintParam	( PrintParams * p );


	/**
	*	@brief	remove a printer setting from here
	*/
	int								printParamIndex		( PrintParams * p )
	{ return print_params_.indexOf( p ); }


	///@}
	/* ******************************************************************* */





	/* ******************************************************************* */
	/** @name 	Properties spport                                          */
	/* ******************************************************************* */
	///@{


	/**
	*	@brief	get the string of properties
	*/
	PropIndex *		properties			(
			int &					count
			) const
	{
		count = 0;
		return NULL;
	}


//	/**
//	*	@brief	change a property using an index
//	*/
//	bool			setProp				(
//			PropIndex				idx,
//			const QString &			value
//			);


//	/**
//	*	@brief	change a property using an index
//	*/
//	bool			setProp				(
//			PropIndex				idx,
//			qreal					value
//			);


//	/**
//	*	@brief	change a property using an index
//	*/
//	bool			setProp				(
//			PropIndex				idx,
//			int						value
//			);


//	/**
//	*	@brief	change a property using an index
//	*/
//	bool			setProp				(
//			PropIndex				idx,
//			void *					value
//			);


//	/**
//	*	@brief	get the value for a property using an index
//	*/
//	QVariantList	getProp				(
//			PropIndex				idx
//			);



	///@}
	/* ******************************************************************* */


protected:

	/**
	*	@brief	raise a signal indicating the space was created
	*/
	void			raiseSpaceCreated			( void );


	/**
	*	@brief	raise a signal indicating the space was created
	*/
	void			raiseSpaceDeleted			( void );




public:

	/**
	*	@brief	creates a default space for specified document
	*
	*	This takes care of all aspects like signaling, creating default
	*	print parameters, ...
	*
	*	It does not take care of inserting itself into an undo atom.
	*/
	static PgSpace *				createDefault		(
			CpgDoc *				doc,
			const QString &		s_name
			);


	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//

};	/*	class PgSpace	*/

/*  CLASS    =============================================================== */
//
//
//
//

}	//	namespace	cpg

#endif // __PGSPACE_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
